package com.lh.center.common.web.handle;

import com.lh.center.common.base.DataAuthSessionUser;
import com.lh.center.common.base.session.AccessDataPermission;
import com.lh.center.common.base.session.CurrentSessionUserPermission;
import com.lh.center.common.base.session.SessionUser;
import com.lh.center.common.constant.GlobalConstant;
import com.lh.center.common.constant.RedisPrefix;
import com.lh.center.common.util.LoggerUtil;
import com.lh.center.common.util.SpringUtils;
import com.lh.center.common.web.advice.BeforeRequestAdvice;
import com.lh.center.common.web.advice.DefaultBeforeRequestAdvice;
import com.lh.center.common.web.session.SessionOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
 * 请求前置校验
 */
@Slf4j
@Component
public class BeforeRequestHandle implements HandlerInterceptor {

    @Lazy
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 访问接口之前执行
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if ("OPTIONS".equals(request.getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);
            return true;
        }

        LoggerUtil.debug(this.getClass(),"进入PreHandle,当前uri:{}",request.getRequestURI());

        SessionOperation.clear();
        //清除当前用户的数据权限缓存
        CurrentSessionUserPermission.clear();
        SessionOperation.request();
        String tranceId = request.getHeader(GlobalConstant.header_log_trance_id);
        if(StringUtils.isNotBlank(tranceId)){
            LoggerUtil.setTranceId(tranceId);
        }
        SessionOperation.getUserNotException();
        return process(request);
    }

    public boolean process(HttpServletRequest request) {
        BeforeRequestAdvice advice = SpringUtils.getBean(BeforeRequestAdvice.class);
        if(advice == null){
            advice = new DefaultBeforeRequestAdvice();
        }
        advice.beforeAuth(request);
        String contentType = request.getContentType();
        if(StringUtils.isNotBlank(contentType) && contentType.toLowerCase().contains("json")){
            if(SessionOperation.toLog.get()){
                LoggerUtil.info(this.getClass(),"收到【{}】接口请求",request.getRequestURI());
            }
        }
        if(!SessionOperation.requireAuth()){
            return true;
        }
        SessionUser user = SessionOperation.getUser();
        SessionOperation.refresh();
        advice.afterAuth(request);
        //保存数据权限
        if(user instanceof DataAuthSessionUser){
            DataAuthSessionUser merchantSessionUser = (DataAuthSessionUser) user;
            Integer dataAuth = merchantSessionUser.getDataAuth();
            AccessDataPermission.DataPermissionType type = AccessDataPermission.DataPermissionType.self;
            if(!dataAuth.equals(GlobalConstant.ZERO)){
                type = AccessDataPermission.DataPermissionType.ins;
            }
            CurrentSessionUserPermission.set(type,merchantSessionUser.getUserId(),merchantSessionUser.getDataInsIds());
            CurrentSessionUserPermission.get().setAdminType(merchantSessionUser.getAdminType());
        }
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        LoggerUtil.debug(this.getClass(),"BeforeRequestHandle,afterCompletion============");
        String limitKey = request.getHeader(RedisPrefix.ONCE_LIMIT_FILTER);
        if(StringUtils.isNotBlank(limitKey)){
            stringRedisTemplate.delete(RedisPrefix.ONCE_LIMIT_FILTER+limitKey);
        }

        if (null == SessionOperation.toLog || null == SessionOperation.toLog.get()){
            LoggerUtil.info(this.getClass(),"this request is not log---------------");
        } else {
//            if(SessionOperation.toLog.get()){
//                SessionUser user = SessionOperation.getUserNotException();
//                SessionUser copy = new SessionUser();
//                if(user != null){
//                    BeanUtils.copyProperties(user,copy);
//                }
//                StringBuilder sb = new StringBuilder();
//                sb.append("请求接口:").append(SessionOperation.getRequest().getRequestURI()).append(",");
//                if(SessionOperation.getConfiguration().isLogWithUser()){
//                    sb.append("当前用户:").append(JSONUtil.toJsonStr(copy)).append(",");
//                }
//                String clientIP = ServletUtil.getClientIP(request);
//                sb.append("客户端ip:").append(clientIP).append(",");
//                if(SessionOperation.getConfiguration().isLogWithRequest()){
//                    Object body = Optional.ofNullable(SessionOperation.requestParams.get()).orElse(new Object());
//                    sb.append("请求参数:").append(JSONUtil.toJsonStr(body)).append(",");
//                }
//                if(SessionOperation.getConfiguration().isLogWithResponse()){
//                    Object responseBody = Optional.ofNullable(SessionOperation.responseParams.get()).orElse(new Object());
//                    sb.append("响应参数:").append(JSONUtil.toJsonStr(responseBody));
//                }
//                LoggerUtil.info(BeforeRequestHandle.class, sb.toString());
//            }
        }

        if(handler instanceof HandlerMethod){
            HandlerMethod hm = (HandlerMethod) handler;
            Method method = hm.getMethod();
            BeforeRequestAdvice advice = SpringUtils.getBean(BeforeRequestAdvice.class);
            if(advice == null){
                advice = new DefaultBeforeRequestAdvice();
            }
            advice.beforeCompletion(request,method);
        }
        //移除掉保存的当前登陆用户的Token
        SessionOperation.clear();
        //清除当前用户的数据权限缓存
        CurrentSessionUserPermission.clear();
    }
}
